package com.qiyang.contoller;

import com.qiyang.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.SessionAttribute;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.Map;

/**
 * Created on 2020/12/10.
 *
 * @author qiyang.
 * 描述：
 */
@Controller
@RequestMapping("/resolve")
//@SessionAttributes("type") // 从model中获取type放入Session中，作用到类下面所有的方法
public class ResolveController {

    /**
     * 响应逻辑视图名
     * @return
     */
    @GetMapping("/index")
    public String index(){
        System.out.println("index");
        // return "/WEB-INF/views/index.jsp";
        return "index";
    }


    /**
     * 使用传统request传参
     * @return
     */
    @GetMapping("/servletApi")
    public String servletApi(HttpServletRequest request){
        request.setAttribute("name", "qiyang");
        return "servletApi";
    }

    /**
     * 使用model传参
     * @return
     */
    @GetMapping("/model")
    public String model(Model model){
        // 底层也是将model的属性赋值到request中
        model.addAttribute("name", "qiyang");
        return "servletApi";
    }

    /**
     * 使用model传参
     * @return
     */
    @GetMapping("/modelMap")
    public String modelMap(ModelMap model){
        // 底层也是将model的属性赋值到request中
        model.addAttribute("name", "qiyang");
        return "servletApi";
    }

    /**
     * 使用model传参
     * @return
     */
    @GetMapping("/map")
    public String modelMap(Map map){
        // 底层也是将model的属性赋值到request中
        // 底层实现都是BindingAwareModelMap
        System.out.println(map.getClass());
        map.put("name", "qiyang");
        return "servletApi";
    }

    /**
     * 使用modelAndView
     * 既封装了model也封装了view
     * @return
     */
    @GetMapping("/modelAndView")
    public ModelAndView modelAndView(){

        // 通过构造函数指定视图名称
        ModelAndView modelAndView = new ModelAndView("servletApi");

        // modelAndView.setViewName(); // 也可以通过set方法设置视图名称

        // 设置参数
        modelAndView.addObject("name", "qiyang");

        return modelAndView;
    }

    /**
     * 使用Servlet HttpSession
     * @return
     */
    @GetMapping("/servlet/sessoin")
    public String servletSession(HttpSession session){

        session.setAttribute("nickname", "钦诚");

        return "sessionApi";
    }

    @Autowired
    HttpSession session;

    /**
     * 使用HttpSession
     * @return
     */
    @GetMapping("/autowired/sessoin")
    public String autowiredSession(){

        session.setAttribute("nickname", "钦诚");

        return "sessionApi";
    }

    /**
     * 获取Session属性
     * SessionAttribute 与 model互通，SessionAttribute可以通过model写入属性
     * model也会自动写入sesion中的属性，此机制在使用注解时才生效
     * 这种注解不太推荐使用，推荐使用自动注入的方式
     * @return
     */
    @GetMapping("/annotation/sessoin")
    public String annotationSession(@SessionAttribute(value = "nickname", required = false)String nickname){

        System.out.println("nickname=" + nickname);

        return "sessionApi";
    }

    HttpSession session2;

    /**
     * 可通过ModelAttribute给全局参数赋值
     * 使用场景：统一在更新某个数据前，先进行查询,填充无需更新的字段，统一处理Session
     * 不推荐使用，作为了解
     */
    @ModelAttribute
    public void showModelAttribute(HttpSession session,Model model){
        System.out.println("会在当前控制器中所有的方法前调用");
        this.session2 = session;
        // model.addAttribute()
    }

    /**
     * Spring还有个机制，会将传入的参数，隐式的设置到request域当中！
     * user 会自动 被设置到request域中
     */
    @GetMapping("user")
    public String getUser(User user){

        return "index";
    }

    /**
     * 转发演示
     */
    @GetMapping("forward")
    public String forward(){
        // 若想转发的视图不参与视图解析器配置的前后缀，加forward，自己写完整的目录及视图名称即可
        return "forward:/params.jsp";
    }

    /**
     * 重定向演示
     */
    @GetMapping("redirect")
    public String redirect(){
        // 不参与视图解析器的解析，SpringMVC会自动加上项目名，Servlet则需要自己获取项目名加上
        // 重定向到WEB-INF/ 下的资源是否可行？WEB-INF是受限的，不可重定向访问
        return "redirect:/params.jsp";
    }

}
